﻿namespace MyTRCP.Common.Models
{
    public class AudioPayload
    {
        public AudioPayloadTypeEnum PayloadType { get; set; }
        public byte[] Datas { get; set; }
        public AudioPayload(AudioPayloadTypeEnum payloadType, byte[] dataBuf, int pos, int len)
        {
            if (dataBuf == null)
            {
                throw new ArgumentNullException(nameof(dataBuf), "缓冲区未初始化");
            }
            if (dataBuf.Length < pos + len)
            {
                throw new ArgumentException("缓冲区长度不足", nameof(dataBuf));
            }
            PayloadType = payloadType;
            Datas = new byte[len];
            Array.Copy(dataBuf, pos, Datas, 0, len);
        }
        public static byte[] Pack(AudioPayload payload)
        {
            byte[] fixedDatas = new byte[payload.Datas.Length * 2];
            int fixedPos = 0;
            for (int i = 0; i < payload.Datas.Length; i++)
            {
                if (payload.Datas[i] == 0x7d || payload.Datas[i] == 0x7e)
                {
                    fixedDatas[fixedPos] = 0x7d;
                    fixedPos++;
                    fixedDatas[fixedPos] = (byte)(payload.Datas[i] ^ 0x20);
                }
                else
                {
                    fixedDatas[fixedPos] = payload.Datas[i];
                }
                fixedPos++;
            }
            byte[] package = new byte[fixedPos + 3];
            package[0] = 0x7e;
            package[1] = (byte)payload.PayloadType;
            if (fixedPos > 0)
            {
                Array.Copy(fixedDatas, 0, package, 2, fixedPos);
            }
            package[fixedPos + 2] = 0x7e;
            return package;
        }
        public static AudioPayload Unpack(byte[] buf, int pos, int length)
        {
            if (buf == null)
            {
                throw new ArgumentNullException(nameof(buf), "缓冲区未初始化");
            }
            if (buf.Length < pos + length)
            {
                throw new ArgumentException("缓冲区长度不足", nameof(buf));
            }
            if (buf[pos] != 0x7e)
            {
                throw new ArgumentException("包头不正确", nameof(buf));
            }
            if (buf[pos + length - 1] != 0x7e)
            {
                throw new ArgumentException("包尾不正确", nameof(buf));
            }
            if (length < 3)
            {
                throw new ArgumentOutOfRangeException(nameof(length), "长度过小");
            }
            int realDataLength = 0;
            AudioPayloadTypeEnum payloadType = (AudioPayloadTypeEnum)buf[pos + 1];
            byte[] data = new byte[length - 3];
            for (int i = 2; i < length - 1; i++)
            {
                if (buf[pos + i] == 0x7d)
                {
                    i++;
                    data[realDataLength] = (byte)(buf[pos + i] ^ 0x20);
                }
                else
                {
                    data[realDataLength] = buf[pos + i];
                }
                realDataLength++;
            }
            return new AudioPayload(payloadType, data, 0, realDataLength);
        }
    }
}